Python๊ณผ InfluxDB๋ฅผ ํ์ฉํ์ฌ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌ, ์ ์ฅ, ๋ถ์ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ์ธ์. ์ด ์ฌ์ธต ๊ฐ์ด๋๋ ์ค์ , ๋ฐ์ดํฐ ์ฐ๊ธฐ, Flux ์ฟผ๋ฆฌ, ๊ฐ๋ฐ์ ๋ฐ ๋ฐ์ดํฐ ๊ณผํ์๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.
์๊ณ์ด ๋ฐ์ดํฐ ๋ง์คํฐํ๊ธฐ: Python๊ณผ InfluxDB ํตํฉ์ ์ํ ์ข ํฉ ๊ฐ์ด๋
์ค๋๋ ์ ๋ฐ์ดํฐ ์ค์ฌ ์ธ์์์ ํน์ ์ ํ์ ๋ฐ์ดํฐ๊ฐ ์๋ง์ ์ฐ์ ์์ ์ ์ ๋ ์ค์ํด์ง๊ณ ์์ต๋๋ค: ์๊ณ์ด ๋ฐ์ดํฐ. DevOps ํ์ดํ๋ผ์ธ์์ ์๋ฒ ์งํ๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ IoT ๋คํธ์ํฌ์์ ์ผ์ ํ๋ ๊ฐ์ ์ถ์ ํ๋ ๊ฒ๋ถํฐ ๊ธ์ต ์์ฅ์์ ์ฃผ๊ฐ๋ฅผ ๋ถ์ํ๋ ๊ฒ์ ์ด๋ฅด๊ธฐ๊น์ง, ํ์์คํฌํ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ ํฌ์ธํธ๋ ์ด๋์๋ ์์ต๋๋ค. ํ์ง๋ง ์ด๋ฌํ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๊ธฐ์กด ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ํด๊ฒฐํ๋๋ก ์ค๊ณ๋์ง ์์ ๊ณ ์ ํ ๊ณผ์ ๋ฅผ ์ ์ํฉ๋๋ค.
๋ฐ๋ก ์ด ์ง์ ์์ ์ ๋ฌธ ์๊ณ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค(TSDB)๊ฐ ๋ฑ์ฅํฉ๋๋ค. ์ด ๋ถ์ผ์ ์ ๋ ์ฃผ์ ์ค ํ๋๋ ํ์์คํฌํ๊ฐ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํน๋ณํ ์ ์๋ ๊ณ ์ฑ๋ฅ ์คํ ์์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ธ InfluxDB์ ๋๋ค. Python์ ๋ค์์ฑ๊ณผ ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ๊ณผํ ์ํ๊ณ์ ๊ฒฐํฉ๋ ๋, ํ์ฅ ๊ฐ๋ฅํ๊ณ ํต์ฐฐ๋ ฅ ์๋ ์๊ณ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๋๋๋๋ก ๊ฒฌ๊ณ ํ ์คํ์ ๋ง๋ญ๋๋ค.
์ด ์ข ํฉ ๊ฐ์ด๋๋ Python์ InfluxDB์ ํตํฉํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ ์๋ดํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๊ธฐ๋ณธ ๊ฐ๋ , ํ๊ฒฝ ์ค์ , ๋ฐ์ดํฐ ์์ฑ ๋ฐ ์ฟผ๋ฆฌ, ์ค์ ์ฌ๋ก, ๊ทธ๋ฆฌ๊ณ ํ๋ก๋์ ์ค๋น ์์คํ ๊ตฌ์ถ์ ์ํ ํ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค. ๋ฐ์ดํฐ ์์ง๋์ด, DevOps ์ ๋ฌธ๊ฐ ๋๋ ๋ฐ์ดํฐ ๊ณผํ์์ด๋ ๊ด๊ณ์์ด ์ด ๊ธฐ์ฌ๋ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ๋ง์คํฐํ๋ ๋ฐ ํ์ํ ๊ธฐ์ ์ ์ ๊ณตํ ๊ฒ์ ๋๋ค.
ํต์ฌ ๊ฐ๋ ์ดํด
์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ ์ InfluxDB์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์คํค๋ง๋ฅผ ์ค๊ณํ๊ณ ํจ๊ณผ์ ์ธ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
InfluxDB๋ ๋ฌด์์ธ๊ฐ์?
InfluxDB๋ ์๊ณ์ด ๋ฐ์ดํฐ์ ๋น ๋ฅด๊ณ ๊ณ ๊ฐ์ฉ์ฑ ์ ์ฅ ๋ฐ ๊ฒ์์ ์ต์ ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๋ค. PostgreSQL ๋๋ MySQL๊ณผ ๊ฐ์ ๋ฒ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฌ๋ฆฌ, InfluxDB์ ๋ด๋ถ ์ํคํ ์ฒ๋ ์๊ณ์ด ์ํฌ๋ก๋์ ํน์ ํจํด, ์ฆ ๋๋ ์ฐ๊ธฐ ๋ฐ ์๊ฐ ์ค์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ฒ์๋ถํฐ ์ค๊ณ๋์์ต๋๋ค.
๋ ๊ฐ์ง ์ฃผ์ ๋ฒ์ ์ผ๋ก ์ ๊ณต๋ฉ๋๋ค:
- InfluxDB OSS: ์์ฒด ์ธํ๋ผ์ ํธ์คํ ํ ์ ์๋ ์คํ ์์ค ๋ฒ์ .
- InfluxDB Cloud: ์์ ๊ด๋ฆฌํ ๋ฉํฐ ํด๋ผ์ฐ๋ DBaaS(Database-as-a-Service) ์ ๊ณต.
์ด ๊ฐ์ด๋์์๋ ๋ ๋ฒ์ ๋ชจ๋์ ์ ์ฉ ๊ฐ๋ฅํ ๊ฐ๋ ์ ์ด์ ์ ๋ง์ถ๊ณ , ์์๋ฅผ ์ํด ๋ก์ปฌ OSS ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
InfluxDB ์ฃผ์ ์ฉ์ด
InfluxDB์๋ ์์ฒด ๋ฐ์ดํฐ ๋ชจ๋ธ๊ณผ ์ฉ์ด๊ฐ ์์ต๋๋ค. ์ด๋ฌํ ์ฉ์ด๋ฅผ ์ดํดํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ฒซ ๋จ๊ณ์ ๋๋ค.
- ๋ฐ์ดํฐ ํฌ์ธํธ (Data Point): InfluxDB์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ๋จ์. ๋จ์ผ ๋ฐ์ดํฐ ํฌ์ธํธ๋ ๋ค ๊ฐ์ง ๊ตฌ์ฑ ์์๋ก ์ด๋ฃจ์ด์ง๋๋ค:
- ์ธก์ (Measurement): SQL์ ํ
์ด๋ธ ์ด๋ฆ๊ณผ ์ ์ฌํ๊ฒ ๋ฐ์ดํฐ์ ์ปจํ
์ด๋ ์ญํ ์ ํ๋ ๋ฌธ์์ด. ์:
cpu_usage๋๋temperature_readings. - ํ๊ทธ ์ธํธ (Tag Set): ๋ฐ์ดํฐ์ ๋ํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํค-๊ฐ ์(๋ชจ๋ ๋ฌธ์์ด)์ ๋ชจ์. ํ๊ทธ๋ ์ธ๋ฑ์ฑ๋์ด ์ฟผ๋ฆฌ์์ ํํฐ๋ง ๋ฐ ๊ทธ๋ฃนํ์ ์ด์์ ์
๋๋ค. ์:
host=server_A,region=us-east-1,sensor_id=T-1000. - ํ๋ ์ธํธ (Field Set): ์ค์ ๋ฐ์ดํฐ ๊ฐ์ ๋ํ๋ด๋ ํค-๊ฐ ์์ ๋ชจ์. ํ๋ ๊ฐ์ ์ ์, ๋ถ๋ ์์์ , ๋ถ์ธ ๋๋ ๋ฌธ์์ด์ผ ์ ์์ต๋๋ค. ํ๋๋ ์ธ๋ฑ์ฑ๋์ง ์์ผ๋ฏ๋ก ์ฟผ๋ฆฌ `WHERE` ์ ์์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ด๋ ต์ต๋๋ค. ์:
value=98.6,load=0.75,is_critical=false. - ํ์์คํฌํ (Timestamp): ๋ฐ์ดํฐ ํฌ์ธํธ์ ๊ด๋ จ๋ ํ์์คํฌํ๋ก, ๋๋ ธ์ด ์ ๋ฐ๋๋ฅผ ๊ฐ์ง๋๋ค. ์ด๋ InfluxDB์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์ฑํ๋ ์ค์ฌ ์์น์ ๋๋ค.
- ์ธก์ (Measurement): SQL์ ํ
์ด๋ธ ์ด๋ฆ๊ณผ ์ ์ฌํ๊ฒ ๋ฐ์ดํฐ์ ์ปจํ
์ด๋ ์ญํ ์ ํ๋ ๋ฌธ์์ด. ์:
- ๋ฒํท (Bucket): ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ์ด๋ฆ ์ง์ ๋ ์์น. ์ ํต์ ์ธ RDBMS์ '๋ฐ์ดํฐ๋ฒ ์ด์ค'์ ์ ์ฌํฉ๋๋ค. ๋ฒํท์๋ ๋ฐ์ดํฐ๊ฐ ๋ณด๊ด๋๋ ๊ธฐ๊ฐ์ ์ ์ํ๋ ๋ณด์กด ์ ์ฑ ์ด ์์ต๋๋ค.
- ์กฐ์ง (Organization, Org): ์ฌ์ฉ์ ๊ทธ๋ฃน์ ์ํ ์์ ๊ณต๊ฐ. ๋ฒํท, ๋์๋ณด๋, ์์ ๊ณผ ๊ฐ์ ๋ชจ๋ ๋ฆฌ์์ค๋ ์กฐ์ง์ ์ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์๊ฐํด๋ณด์ธ์: ์จ๋ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋กํ๋ ๊ฒฝ์ฐ, ์ธก์ (measurement)์ `environment_sensors`์ผ ์ ์์ต๋๋ค. ํ๊ทธ(tags)๋ ๋ฐ์ดํฐ๊ฐ ์ด๋์, ๋ฌด์์ด ์์ฑ๋์๋์ง ์ค๋ช ํ๊ธฐ ์ํด `location=lab_1` ๋ฐ `sensor_type=DHT22`๊ฐ ๋ ์ ์์ต๋๋ค. ํ๋(fields)๋ `temperature=22.5` ๋ฐ `humidity=45.1`์ ๊ฐ์ ์ค์ ํ๋ ๊ฐ์ด ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌผ๋ก , ๋ชจ๋ ํ๋ ๊ฐ์๋ ๊ณ ์ ํ ํ์์คํฌํ๊ฐ ์์ ๊ฒ์ ๋๋ค.
ํ๊ฒฝ ์ค์
์ด์ ํ์ํ ๋๊ตฌ๋ฅผ ์ค์ ํด ๋ด ์๋ค. ๋น ๋ฅด๊ณ ์ ์ญ์ ์ผ๋ก ์ผ๊ด๋ InfluxDB ์ค์ ์ ์ํด Docker๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
Docker๋ก InfluxDB ์ค์น
Docker๋ ์๋น์ค๋ฅผ ์คํํ๊ธฐ ์ํ ๊นจ๋ํ๊ณ ๊ฒฉ๋ฆฌ๋ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค. Docker๊ฐ ์ค์น๋์ด ์์ง ์๋ค๋ฉด, ์ด์ ์ฒด์ ์ ๋ํ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
InfluxDB 2.x ์ปจํ ์ด๋๋ฅผ ์์ํ๋ ค๋ฉด ํฐ๋ฏธ๋์ ์ด๊ณ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์คํํ์ธ์:
docker run --name influxdb -p 8086:8086 influxdb:latest
์ด ๋ช ๋ น์ด๋ ์ต์ InfluxDB ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ๊ณ , `influxdb`๋ผ๋ ์ด๋ฆ์ ์ปจํ ์ด๋๋ฅผ ์์ํ๋ฉฐ, ๋ก์ปฌ ๋จธ์ ์ ํฌํธ 8086์ ์ปจํ ์ด๋ ๋ด๋ถ์ ํฌํธ 8086์ ๋งคํํฉ๋๋ค. ์ด๋ InfluxDB API์ ๊ธฐ๋ณธ ํฌํธ์ ๋๋ค.
InfluxDB ์ด๊ธฐ ์ค์
์ปจํ
์ด๋๊ฐ ์คํ๋๋ฉด ์น ๋ธ๋ผ์ฐ์ ์์ http://localhost:8086์ผ๋ก ์ด๋ํ์ฌ InfluxDB ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
- "Welcome to InfluxDB" ์ค์ ํ๋ฉด์ด ๋ํ๋ฉ๋๋ค. "์์ํ๊ธฐ(Get Started)"๋ฅผ ํด๋ฆญํ์ธ์.
- ์ฌ์ฉ์ ์ค์ : ์ด๊ธฐ ์ฌ์ฉ์๋ฅผ ์์ฑํ๋ผ๋ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค. ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ธ์.
- ์ด๊ธฐ ์กฐ์ง ๋ฐ ๋ฒํท: ๊ธฐ๋ณธ ์กฐ์ง ์ด๋ฆ(์: `my-org`)๊ณผ ์ฒซ ๋ฒ์งธ ๋ฒํท ์ด๋ฆ(์: `my-bucket`)์ ์ ๊ณตํ์ธ์.
- ํ ํฐ ์ ์ฅ: ์ค์ ์๋ฃ ํ, InfluxDB๋ ์ด๊ธฐ ๊ด๋ฆฌ์ ํ ํฐ์ ํ์ํฉ๋๋ค. ์ด๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค! ์ด ํ ํฐ์ ๋ณต์ฌํ์ฌ ์์ ํ ๊ณณ์ ์ ์ฅํ์ธ์. Python ์คํฌ๋ฆฝํธ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ ์์ฉํ๋ ๋ฐ ํ์ํฉ๋๋ค.
์ค์ ํ, InfluxDB ๋ฉ์ธ ๋์๋ณด๋๋ก ์ด๋ํฉ๋๋ค. ์ด์ Python์์ InfluxDB์ ์ฐ๊ฒฐํ ์ค๋น๊ฐ ๋์์ต๋๋ค.
Python ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
InfluxDB 2.x ๋ฐ Cloud์ฉ ๊ณต์ Python ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ `influxdb-client`์ ๋๋ค. ์ค์นํ๋ ค๋ฉด pip๋ฅผ ์ฌ์ฉํ์ธ์:
pip install influxdb-client
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ InfluxDB ์ธ์คํด์ค๋ฅผ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์์ฑ, ์ฟผ๋ฆฌ ๋ฐ ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Python์ผ๋ก ๋ฐ์ดํฐ ์ฐ๊ธฐ
ํ๊ฒฝ์ด ์ค๋น๋์์ผ๋ฏ๋ก, Python์ ์ฌ์ฉํ์ฌ InfluxDB์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ํนํ ๋์ ์ฒ๋ฆฌ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฐ๋ ๊ฒ์ด ์ฑ๋ฅ์ ์ค์ํฉ๋๋ค.
InfluxDB์ ์ฐ๊ฒฐ
๋ชจ๋ ์คํฌ๋ฆฝํธ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ์ฐ๊ฒฐ์ ์ค์ ํ๋ ๊ฒ์ ๋๋ค. URL, ์กฐ์ง ์ด๋ฆ, ๊ทธ๋ฆฌ๊ณ ์ด์ ์ ์ ์ฅํ ํ ํฐ์ด ํ์ํฉ๋๋ค.
ํ ํฐ๊ณผ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์คํฌ๋ฆฝํธ์ ํ๋์ฝ๋ฉํ๋ ๋์ ํ๊ฒฝ ๋ณ์์ ์ ์ฅํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด ์์์์๋ ๋ช ํ์ฑ์ ์ํด ๋ณ์๋ก ์ ์ํ๊ฒ ์ต๋๋ค.
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS
# --- Connection Details ---
url = "http://localhost:8086"
token = "YOUR_SUPER_SECRET_TOKEN" # Replace with your actual token
org = "my-org"
bucket = "my-bucket"
# --- Instantiate the Client ---
client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
# --- Get the Write API ---
# SYNCHRONOUS mode writes data immediately. For high-throughput, consider ASYNCHRONOUS.
write_api = client.write_api(write_options=SYNCHRONOUS)
print("Successfully connected to InfluxDB!")
๋จ์ผ ๋ฐ์ดํฐ ํฌ์ธํธ ๊ตฌ์กฐํ ๋ฐ ์์ฑ
ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ InfluxDB ๋ฐ์ดํฐ ๋ชจ๋ธ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ํธ๋ฆฌํ๊ฒ ๊ตฌ์กฐํํ ์ ์๋ `Point` ๊ฐ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
์๋ฒ์ CPU ๋ก๋๋ฅผ ๋ํ๋ด๋ ๋จ์ผ ๋ฐ์ดํฐ ํฌ์ธํธ๋ฅผ ์์ฑํด ๋ด ์๋ค.
from influxdb_client import Point
import time
# Create a data point using the fluent API
point = (
Point("system_metrics")
.tag("host", "server-alpha")
.tag("region", "eu-central-1")
.field("cpu_load_percent", 12.34)
.field("memory_usage_mb", 567.89)
.time(int(time.time_ns())) # Use nanosecond precision timestamp
)
# Write the point to the bucket
write_api.write(bucket=bucket, org=org, record=point)
print(f"Wrote a single point to '{bucket}'.")
์ด ์์์์ `system_metrics`๋ ์ธก์ (measurement)์ด๊ณ , `host`์ `region`์ ํ๊ทธ์ด๋ฉฐ, `cpu_load_percent`์ `memory_usage_mb`๋ ํ๋์ ๋๋ค. ์ฐ๋ฆฌ๋ `time.time_ns()`๋ฅผ ์ฌ์ฉํ์ฌ InfluxDB์ ๊ธฐ๋ณธ ์ ๋ฐ๋์ธ ๋๋ ธ์ด ์ ๋ฐ๋๋ก ํ์ฌ ํ์์คํฌํ๋ฅผ ์ป์ต๋๋ค.
์ฑ๋ฅ์ ์ํ ๋ฐฐ์น ์ฐ๊ธฐ
๋ฐ์ดํฐ ํฌ์ธํธ๋ฅผ ํ๋์ฉ ์ฐ๋ ๊ฒ์ ๋นํจ์จ์ ์ด๋ฉฐ ๋ถํ์ํ ๋คํธ์ํฌ ์ค๋ฒํค๋๋ฅผ ๋ฐ์์ํต๋๋ค. ๋ชจ๋ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ฐ๊ธฐ๋ฅผ ๋ฐฐ์น ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. `write_api`๋ `Point` ๊ฐ์ฒด ๋ชฉ๋ก์ ๋ฐ์ ์ ์์ต๋๋ค.
์ฌ๋ฌ ์ผ์ ํ๋ ๊ฐ์ ์์งํ์ฌ ๋จ์ผ ๋ฐฐ์น๋ก ์์ฑํ๋ ๊ฒ์ ์๋ฎฌ๋ ์ด์ ํด ๋ด ์๋ค.
points = []
# Simulate 5 readings from two different sensors
for i in range(5):
# Sensor 1
point1 = (
Point("environment")
.tag("sensor_id", "A001")
.tag("location", "greenhouse-1")
.field("temperature", 25.1 + i * 0.1)
.field("humidity", 60.5 + i * 0.2)
.time(int(time.time_ns()) - i * 10**9) # Stagger timestamps by 1 second
)
points.append(point1)
# Sensor 2
point2 = (
Point("environment")
.tag("sensor_id", "B002")
.tag("location", "greenhouse-2")
.field("temperature", 22.8 + i * 0.15)
.field("humidity", 55.2 - i * 0.1)
.time(int(time.time_ns()) - i * 10**9)
)
points.append(point2)
# Write the entire batch of points
write_api.write(bucket=bucket, org=org, record=points)
print(f"Wrote a batch of {len(points)} points to '{bucket}'.")
์ด ์ ๊ทผ ๋ฐฉ์์ InfluxDB API๋ก ์ ์ก๋๋ HTTP ์์ฒญ ์๋ฅผ ์ค์ฌ ์ฐ๊ธฐ ์ฒ๋ฆฌ๋์ ํฌ๊ฒ ํฅ์์ํต๋๋ค.
Pandas DataFrame์์ ๋ฐ์ดํฐ ์ฐ๊ธฐ
๋ฐ์ดํฐ ๊ณผํ์์ ๋ถ์๊ฐ์๊ฒ Pandas๋ ์ ํ์ ๋๊ตฌ์ ๋๋ค. `influxdb-client` ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Pandas DataFrame์์ ์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ ๊ฒ์ ์ผ๋ฑ ์ง์ํ๋ฉฐ, ์ด๋ ์์ฒญ๋๊ฒ ๊ฐ๋ ฅํฉ๋๋ค.
ํด๋ผ์ด์ธํธ๋ DataFrame ์ด์ ์ธก์ (measurements), ํ๊ทธ, ํ๋ ๋ฐ ํ์์คํฌํ์ ์๋์ผ๋ก ๋งคํํ ์ ์์ต๋๋ค.
import pandas as pd
import numpy as np
# Create a sample DataFrame
now = pd.Timestamp.now(tz='UTC')
dates = pd.to_datetime([now - pd.Timedelta(minutes=i) for i in range(10)])
data = {
'price': np.random.uniform(100, 110, 10),
'volume': np.random.randint(1000, 5000, 10),
'symbol': 'XYZ',
'exchange': 'GLOBALEX'
}
df = pd.DataFrame(data=data, index=dates)
# The DataFrame must have a timezone-aware DatetimeIndex
print("Sample DataFrame:")
print(df)
# Write the DataFrame to InfluxDB
# data_frame_measurement_name: The measurement name to use
# data_frame_tag_columns: Columns to be treated as tags
write_api.write(
bucket=bucket,
record=df,
data_frame_measurement_name='stock_prices',
data_frame_tag_columns=['symbol', 'exchange']
)
print(f"\nWrote DataFrame to measurement 'stock_prices' in bucket '{bucket}'.")
# Remember to close the client
client.close()
์ด ์์์์๋ DataFrame์ ์ธ๋ฑ์ค๊ฐ ์๋์ผ๋ก ํ์์คํฌํ๋ก ์ฌ์ฉ๋ฉ๋๋ค. `symbol` ๋ฐ `exchange` ์ด์ ํ๊ทธ๋ก ์ง์ ํ๊ณ , ๋๋จธ์ง ์ซ์ ์ด(`price` ๋ฐ `volume`)์ ํ๋๊ฐ ๋ฉ๋๋ค.
Python๊ณผ Flux๋ก ๋ฐ์ดํฐ ์ฟผ๋ฆฌํ๊ธฐ
๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ฒ์ ์ ๋ฐ์ ์ ํฌ์ ๋ถ๊ณผํฉ๋๋ค. ์ง์ ํ ํ์ ๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌํ๊ณ ๋ถ์ํ ์ ์๋ ๋ฅ๋ ฅ์์ ๋์ต๋๋ค. InfluxDB 2.x๋ Flux๋ผ๋ ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ์คํฌ๋ฆฝํ ์ธ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Flux ์๊ฐ
Flux๋ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌ, ๋ถ์ ๋ฐ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๊ณ๋ ํจ์ํ ์ธ์ด์ ๋๋ค. ํ์ดํ-ํฌ์๋ ์ฐ์ฐ์(`|>`)๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ์ฐ๊ฒฐํ๋ฉฐ, ์ฝ๊ธฐ ์ฝ๊ณ ํํ๋ ฅ์ด ํ๋ถํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ์์ฑํฉ๋๋ค.
๊ฐ๋จํ Flux ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
from(bucket: "my-bucket")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "system_metrics")
|> filter(fn: (r) => r.host == "server-alpha")
์ด ์ฟผ๋ฆฌ๋ `my-bucket`์์ ๋ฐ์ดํฐ๋ฅผ ์ ํํ๊ณ , ์ง๋ 1์๊ฐ์ผ๋ก ํํฐ๋งํ ๋ค์, ํน์ ์ธก์ (measurement)๊ณผ ํธ์คํธ ํ๊ทธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ถ๊ฐ ํํฐ๋งํฉ๋๋ค.
Python์์ ์ฒซ Flux ์ฟผ๋ฆฌ
๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌํ๋ ค๋ฉด ํด๋ผ์ด์ธํธ์์ `QueryAPI` ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
# --- Re-establish connection for querying ---
client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
query_api = client.query_api()
# --- Define the Flux query ---
flux_query = f'''
from(bucket: "{bucket}")
|> range(start: -10m)
|> filter(fn: (r) => r._measurement == "environment")
'''
# --- Execute the query ---
result_tables = query_api.query(query=flux_query, org=org)
print("Query executed. Processing results...")
์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์ฒ๋ฆฌ
Flux ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ ํ ์ด๋ธ ์คํธ๋ฆผ์ ๋๋ค. ๊ฐ ํ ์ด๋ธ์ ๊ณ ์ ํ ๋ฐ์ดํฐ ํฌ์ธํธ ๊ทธ๋ฃน(์ธก์ , ํ๊ทธ ๋ฑ์ผ๋ก ๊ทธ๋ฃนํ๋จ)์ ๋ํ๋ ๋๋ค. ์ด ํ ์ด๋ธ๊ณผ ํด๋น ๋ ์ฝ๋๋ฅผ ๋ฐ๋ณตํ ์ ์์ต๋๋ค.
# Iterate through tables
for table in result_tables:
print(f"--- Table (series for tags: {table.records[0].values}) ---")
# Iterate through records in each table
for record in table.records:
print(f"Time: {record.get_time()}, Field: {record.get_field()}, Value: {record.get_value()}")
print("\nFinished processing query results.")
์ด ์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์ ์ ๋ ผ๋ฆฌ์ ์ ์ฉํ์ง๋ง, ๋ฐ์ดํฐ ๋ถ์์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์น์ํ ๊ตฌ์กฐ๋ก ์ง์ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ๋ ํธ๋ฆฌํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
๊ณ ๊ธ ์ฟผ๋ฆฌ: ์ง๊ณ ๋ฐ ๋ณํ
Flux๋ ์ง๊ณ๋ฅผ ์ํํ ๋ ์ง์ ์ผ๋ก ๋น์ ๋ฐํฉ๋๋ค. ์ด์ ์ ์์ฑํ `environment` ๋ฐ์ดํฐ์ ๋ํด 2๋ถ๋ง๋ค ํ๊ท ์จ๋๋ฅผ ์ฐพ์๋ด ์๋ค.
flux_aggregate_query = f'''
from(bucket: "{bucket}")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "environment")
|> filter(fn: (r) => r._field == "temperature")
|> window(every: 2m)
|> mean()
|> yield(name: "mean_temperature")
'''
# Execute and process
aggregated_results = query_api.query(query=flux_aggregate_query, org=org)
print("\n--- Aggregated Results (Average Temperature per 2m) ---")
for table in aggregated_results:
for record in table.records:
print(f"Time Window End: {record.get_time()}, Average Temp: {record.get_value():.2f}")
์ฌ๊ธฐ์ `window(every: 2m)`๋ ๋ฐ์ดํฐ๋ฅผ 2๋ถ ๊ฐ๊ฒฉ์ผ๋ก ๊ทธ๋ฃนํํ๊ณ , `mean()`์ ๊ฐ ์ฐฝ์ ๋ํ ํ๊ท ๊ฐ์ ๊ณ์ฐํฉ๋๋ค.
Pandas DataFrame์ผ๋ก ์ง์ ์ฟผ๋ฆฌํ๊ธฐ
InfluxDB๋ฅผ Python ๋ฐ์ดํฐ ๊ณผํ ์คํ๊ณผ ํตํฉํ๋ ๊ฐ์ฅ ์ํํ ๋ฐฉ๋ฒ์ Pandas DataFrame์ผ๋ก ์ง์ ์ฟผ๋ฆฌํ๋ ๊ฒ์ ๋๋ค. `query_api`์๋ ์ด๋ฅผ ์ํ ์ ์ฉ ๋ฉ์๋์ธ `query_data_frame()`์ด ์์ต๋๋ค.
# --- Query stock prices into a DataFrame ---
flux_df_query = f'''
from(bucket: "{bucket}")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "stock_prices")
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
'''
# Execute the query
df_result = query_api.query_data_frame(query=flux_df_query, org=org)
# The result might have extra columns, let's clean it up
if not df_result.empty:
df_result = df_result[['_time', 'symbol', 'price', 'volume']]
df_result.set_index('_time', inplace=True)
print("\n--- Query Result as Pandas DataFrame ---")
print(df_result)
else:
print("\nQuery returned no data.")
client.close()
์ฌ๊ธฐ์ Flux์ `pivot()` ํจ์๊ฐ ์ค์ํฉ๋๋ค. ์ด ํจ์๋ ๋ฐ์ดํฐ๋ฅผ InfluxDB์ ๊ธด ํ์(ํ๋๋น ํ ํ)์์ ๋์ ํ์(๊ฐ ํ๋์ ๋ํ ์ด)์ผ๋ก ๋ณํํ๋๋ฐ, ์ด๋ ์ผ๋ฐ์ ์ผ๋ก DataFrame์์ ์์ํ๋ ํ์์ ๋๋ค. ์ด์ ๋ฐ์ดํฐ๊ฐ Pandas์ ์์ผ๋ฏ๋ก Matplotlib, Seaborn ๋๋ scikit-learn๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฐํ ๋ฐ ๋จธ์ ๋ฌ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ค์ ์ฌ์ฉ ์ฌ๋ก: ์์คํ ์งํ ๋ชจ๋ํฐ๋ง
์ค์ ์ฌ๋ก๋ฅผ ํตํด ๋ชจ๋ ๊ฒ์ ํตํฉํด ๋ด ์๋ค: ๋ก์ปฌ ์์คํ ์งํ(CPU ๋ฐ ๋ฉ๋ชจ๋ฆฌ)๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ InfluxDB์ ๊ธฐ๋กํ๋ Python ์คํฌ๋ฆฝํธ์ ๋๋ค.
๋จผ์ `psutil` ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค:
pip install psutil
๋ชจ๋ํฐ๋ง ์คํฌ๋ฆฝํธ
์ด ์คํฌ๋ฆฝํธ๋ 10์ด๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์์ฑํ๋ฉฐ ๋ฌด๊ธฐํ์ผ๋ก ์คํ๋ฉ๋๋ค.
import influxdb_client
from influxdb_client import Point
from influxdb_client.client.write_api import SYNCHRONOUS
import psutil
import time
import socket
# --- Configuration ---
url = "http://localhost:8086"
token = "YOUR_SUPER_SECRET_TOKEN" # Replace with your token
org = "my-org"
bucket = "monitoring"
# Get the hostname to use as a tag
hostname = socket.gethostname()
# --- Main Monitoring Loop ---
def monitor_system():
print("Starting system monitor...")
with influxdb_client.InfluxDBClient(url=url, token=token, org=org) as client:
write_api = client.write_api(write_options=SYNCHRONOUS)
while True:
try:
# Get metrics
cpu_percent = psutil.cpu_percent(interval=1)
memory_percent = psutil.virtual_memory().percent
# Create data points
cpu_point = (
Point("system_stats")
.tag("host", hostname)
.field("cpu_usage_percent", float(cpu_percent))
)
memory_point = (
Point("system_stats")
.tag("host", hostname)
.field("memory_usage_percent", float(memory_percent))
)
# Write batch
write_api.write(bucket=bucket, org=org, record=[cpu_point, memory_point])
print(f"Logged CPU: {cpu_percent}%, Memory: {memory_percent}%")
# Wait for the next interval
time.sleep(10)
except KeyboardInterrupt:
print("\nMonitoring stopped by user.")
break
except Exception as e:
print(f"An error occurred: {e}")
time.sleep(10) # Wait before retrying
if __name__ == "__main__":
# Note: You may need to create the 'monitoring' bucket in the InfluxDB UI first.
monitor_system()
๋ฐ์ดํฐ ์๊ฐํ
์ด ์คํฌ๋ฆฝํธ๋ฅผ ๋ช ๋ถ ๋์ ์คํํ ํ, `http://localhost:8086`์ InfluxDB UI๋ก ๋์๊ฐ์ธ์. ๋ฐ์ดํฐ ํ์๊ธฐ(Data Explorer) (๋๋ ํ์) ํญ์ผ๋ก ์ด๋ํ์ธ์. UI ๋น๋๋ฅผ ์ฌ์ฉํ์ฌ `monitoring` ๋ฒํท, `system_stats` ์ธก์ , ๊ทธ๋ฆฌ๊ณ ์๊ฐํํ๋ ค๋ ํ๋๋ฅผ ์ ํํ์ธ์. Python ์คํฌ๋ฆฝํธ๊ฐ ์ ๊ณตํ๋ ์์คํ ์ CPU ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ค์๊ฐ ๊ทธ๋ํ๋ฅผ ๋ณผ ์ ์์ ๊ฒ์ ๋๋ค!
๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ๊ณ ๊ธ ์ฃผ์
๊ฒฌ๊ณ ํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์์คํ ์ ๊ตฌ์ถํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด์ธ์.
์คํค๋ง ์ค๊ณ: ํ๊ทธ vs. ํ๋
- ์ฟผ๋ฆฌ์ ์ฌ์ฉํ ๋ฉํ๋ฐ์ดํฐ์ ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ธ์. ํ๊ทธ๋ ์ธ๋ฑ์ฑ๋์ด `filter()` ์์ ์ด ๋งค์ฐ ๋น ๋ฆ ๋๋ค. ํ๊ทธ์ ์ข์ ํ๋ณด๋ ํธ์คํธ ์ด๋ฆ, ์ง์ญ, ์ผ์ ID ๋๋ ์ธก์ ๊ฐ์ ์ค๋ช ํ๋ ๋ฎ์-์ค๊ฐ ์นด๋๋๋ฆฌํฐ ๋ฐ์ดํฐ์ ๋๋ค.
- ์์ ๋ฐ์ดํฐ ๊ฐ์๋ ํ๋๋ฅผ ์ฌ์ฉํ์ธ์. ํ๋๋ ์ธ๋ฑ์ฑ๋์ง ์์ผ๋ฏ๋ก ํ๋ ๊ฐ์ผ๋ก ํํฐ๋งํ๋ ๊ฒ์ ํจ์ฌ ๋๋ฆฝ๋๋ค. ๊ฑฐ์ ๋ชจ๋ ๋ฐ์ดํฐ ํฌ์ธํธ์ ํจ๊ป ๋ณ๊ฒฝ๋๋ ๋ชจ๋ ๊ฐ(์จ๋ ๋๋ ๊ฐ๊ฒฉ๊ณผ ๊ฐ์)์ ํ๋์ฌ์ผ ํฉ๋๋ค.
- ์นด๋๋๋ฆฌํฐ๊ฐ ํต์ฌ์ ๋๋ค. ํ๊ทธ์ ๋์ ์นด๋๋๋ฆฌํฐ(๋ง์ ๊ณ ์ ๊ฐ, ๋๊ท๋ชจ ์์คํ ์ ์ฌ์ฉ์ ID์ ๊ฐ์)๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค. ์คํค๋ง๋ฅผ ์ค๊ณํ ๋ ์ด๋ฅผ ์ผ๋์ ๋์ธ์.
์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ๋ณต์๋ ฅ
๋คํธ์ํฌ ์ฐ๊ฒฐ์ ์คํจํ ์ ์์ต๋๋ค. ์ ์ฌ์ ์ธ ์์ธ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํญ์ ์ฐ๊ธฐ ๋ฐ ์ฟผ๋ฆฌ ํธ์ถ์ `try...except` ๋ธ๋ก์ผ๋ก ๋ฌถ์ผ์ธ์. `influxdb-client`์๋ ๋ ๋์ ๋ณต์๋ ฅ์ ์ํด ๊ตฌ์ฑํ ์ ์๋ ๋ด์ฅ๋ ์ฌ์๋ ์ ๋ต๋ ํฌํจ๋์ด ์์ต๋๋ค.
๋ณด์: ํ ํฐ ๊ด๋ฆฌ
- ์์ค ์ฝ๋์ ํ ํฐ์ ์ ๋ ํ๋์ฝ๋ฉํ์ง ๋ง์ธ์. ํ๊ฒฝ ๋ณ์ ๋๋ HashiCorp Vault, AWS Secrets Manager์ ๊ฐ์ ๋น๋ฐ ๊ด๋ฆฌ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ธ์.
- ์ธ๋ถํ๋ ํ ํฐ์ ์ฌ์ฉํ์ธ์. InfluxDB UI์ API ํ ํฐ ์๋์์ ํน์ ๊ถํ์ ๊ฐ์ง ์ ํ ํฐ์ ์์ฑํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ง ์ฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ํน์ ๋ฒํท์ ๋ํ ์ฐ๊ธฐ ์ ์ฉ ์ก์ธ์ค ๊ถํ์ ๊ฐ์ง ํ ํฐ์ ๋ง๋์ธ์. ์ด๋ ์ต์ ๊ถํ์ ์์น์ ๋ฐ๋ฆ ๋๋ค.
๋ฐ์ดํฐ ๋ณด์กด ์ ์ฑ
์๊ณ์ด ๋ฐ์ดํฐ๋ ๋ฏฟ์ ์ ์์ ๋งํผ ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ ์ ์์ต๋๋ค. InfluxDB์ ๋ณด์กด ์ ์ฑ ์ ์ง์ ๋ ๊ธฐ๊ฐ๋ณด๋ค ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ญ์ ํฉ๋๋ค. ๋ฐ์ดํฐ ๋ผ์ดํ์ฌ์ดํด์ ๊ณํํ์ธ์: ๊ณ ํด์๋ ๋ฐ์ดํฐ๋ 30์ผ ๋์ ๋ณด๊ดํ์ง๋ง, ๋ค์ด์ํ๋ง๋๊ณ ์ง๊ณ๋ ๋ฐ์ดํฐ(์: ์ผ์ผ ํ๊ท )๋ ๋ค๋ฅธ ๋ฒํท์ ๋ฌด๊ธฐํ์ผ๋ก ์ ์ฅํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
Python๊ณผ InfluxDB์ ์กฐํฉ์ ๋ชจ๋ ์๊ณ์ด ๋ฐ์ดํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ํ๋ซํผ์ ์ ๊ณตํฉ๋๋ค. ์ฐ๋ฆฌ๋ InfluxDB ๋ฐ์ดํฐ ๋ชจ๋ธ์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ถํฐ ๊ณต์ Python ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ณ ์ฟผ๋ฆฌํ๋ ์ค์ฉ์ ์ธ ์ธก๋ฉด๊น์ง ์ดํด๋ณด์์ต๋๋ค. ๋จ์ผ ํฌ์ธํธ๋ฅผ ์์ฑํ๊ณ , ์ฑ๋ฅ์ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์น ์ฒ๋ฆฌํ๋ฉฐ, ๊ฐ๋ ฅํ Pandas ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํํ๊ฒ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค.
์คํค๋ง ์ค๊ณ, ๋ณด์ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ์ ๋ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด, ์ด์ ํ์ฅ ๊ฐ๋ฅํ๊ณ ๋ณต์๋ ฅ์ด ์์ผ๋ฉฐ ํต์ฐฐ๋ ฅ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ค๋น๊ฐ ์๋ฃ๋์์ต๋๋ค. ์๊ณ์ด ๋ฐ์ดํฐ์ ์ธ๊ณ๋ ๊ด๋ํ๋ฉฐ, ์ด์ ์ด๋ฅผ ํ์ํ ์ ์๋ ๊ธฐ๋ณธ ๋๊ตฌ๋ฅผ ๊ฐ๊ฒ ๋์์ต๋๋ค.
๋ค์ ๋จ๊ณ๋ ์๋ ๋ค์ด์ํ๋ง์ ์ํ InfluxDB์ ํ์คํฌ ์์ง ํ์, ์ด์ ๊ฐ์ง๋ฅผ ์ํ ๊ฒฝ๊ณ ์ค์ , ๋๋ Grafana์ ๊ฐ์ ์๊ฐํ ๋๊ตฌ์์ ํตํฉ์ ํฌํจํ ์ ์์ต๋๋ค. ๊ฐ๋ฅ์ฑ์ ๋ฌดํํฉ๋๋ค. ์ง๊ธ ๋ฐ๋ก ์๊ณ์ด ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ์ ์์ํ์ธ์!